package org.jetlinks.pro.logging;

import org.hswebframework.ezorm.core.param.QueryParam;
import org.hswebframework.reactor.excel.poi.PoiExcelWriter;
import org.hswebframework.reactor.excel.spi.ExcelWriter;
import org.hswebframework.web.api.crud.entity.PagerResult;
import org.jetlinks.core.event.EventBus;
import org.jetlinks.core.metadata.types.StringType;
import org.jetlinks.pro.elastic.search.index.DefaultElasticSearchIndexManager;
import org.jetlinks.pro.elastic.search.index.DefaultElasticSearchIndexMetadata;
import org.jetlinks.pro.elastic.search.index.ElasticIndex;
import org.jetlinks.pro.elastic.search.index.ElasticSearchIndexManager;
import org.jetlinks.pro.elastic.search.index.ElasticSearchIndexStrategy;
import org.jetlinks.pro.elastic.search.service.ElasticSearchService;
import org.jetlinks.pro.logging.event.handler.LoggerIndexProvider;
import org.jetlinks.supports.event.BrokerEventBus;
import org.mockito.Mockito;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.util.Arrays;
import java.util.Collections;

import static org.jetlinks.pro.logging.ElasticSearchServiceUtils.ACCESS_LOG_LIST;
import static org.jetlinks.pro.logging.ElasticSearchServiceUtils.SYSTEM_LOG_LIST;

/**
 * 输入描述.
 *
 * @author zhangji
 * @version 1.11 2021/12/27
 */
@Configuration
public class LoggingTestConfiguration {
    @Bean
    public EventBus eventBus() {
        return new BrokerEventBus();
    }

    @Bean
    public ElasticSearchService elasticSearchService() {
        ElasticSearchService elasticSearchService = Mockito.mock(ElasticSearchService.class);
        Mockito.when(
            elasticSearchService.queryPager(
                Mockito.any(ElasticIndex.class),
                Mockito.any(QueryParam.class),
                Mockito.any(Class.class)))
            .thenAnswer(invocation -> {
                LoggerIndexProvider index = invocation.getArgument(0, LoggerIndexProvider.class);
                return LoggerIndexProvider.ACCESS.equals(index) ?
                    Mono.just(PagerResult.of(ACCESS_LOG_LIST.size(), ACCESS_LOG_LIST)) :
                    Mono.just(PagerResult.of(SYSTEM_LOG_LIST.size(), SYSTEM_LOG_LIST));
            });
        Mockito.when(
            elasticSearchService.query(
                Mockito.any(ElasticIndex.class),
                Mockito.any(QueryParam.class),
                Mockito.any(Class.class)))
            .thenAnswer(invocation -> {
                LoggerIndexProvider index = invocation.getArgument(0, LoggerIndexProvider.class);
                return LoggerIndexProvider.ACCESS.equals(index) ?
                    Flux.fromIterable(ACCESS_LOG_LIST) :
                    Flux.fromIterable(SYSTEM_LOG_LIST);
            });

        return elasticSearchService;
    }

    @Bean
    public ElasticSearchIndexManager elasticSearchIndexManager() {
        ElasticSearchIndexStrategy strategy = Mockito.mock(ElasticSearchIndexStrategy.class);

        Mockito.when(strategy.putIndex(Mockito.any()))
            .thenReturn(Mono.empty());
        Mockito.when(strategy.getId())
            .thenReturn("direct");
        Mockito.when(strategy.getIndexForSearch(Mockito.any()))
            .thenReturn("direct");
        Mockito.when(strategy.getIndexForSave(Mockito.any()))
            .thenReturn("direct");

        String indexName = "index";

        DefaultElasticSearchIndexMetadata metadata = new DefaultElasticSearchIndexMetadata(indexName);
        metadata.addProperty("test", StringType.GLOBAL);

        Mockito.when(strategy.loadIndexMetadata(Mockito.any()))
            .thenReturn(Mono.just(metadata));


        DefaultElasticSearchIndexManager manager = new DefaultElasticSearchIndexManager(Arrays.asList(strategy),
            Collections.emptyList());
        manager.useStrategy(indexName, strategy.getId());

        return manager;
    }

    @Bean
    public ExcelWriter excelWriter() {
        return new PoiExcelWriter();
    }
}
